package tr.com.netgis.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;

import tr.com.netgis.NGApplication;
import tr.com.netgis.R;
import tr.com.netgis.pojo.NGLocation;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;

/**
 * 
 * @author NetGis
 * 
 */
public class Utility {

	/**
	 * Creates date formater with this pattern: yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static SimpleDateFormat createSimpleDateFormat() {
		SimpleDateFormat result = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return result;
	}
	
	/**
	 * dd.MM.yyyy HH:mm:ss
	 * @return
	 */
	public static SimpleDateFormat createSDFDot() {
		SimpleDateFormat result = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
		return result;
	}

	/**
	 * km 
	 * @param first
	 * @param second
	 * @return
	 */
	public static double distance (NGLocation from, NGLocation to) {
		if (from == null || to == null)
			return 0.0;
		return distance(from.getLat(), from.getLon(), to.getLat(), to.getLon(), 'K');
	}
	
	public static float speed (NGLocation from, NGLocation to) {
		float speed = 0;
		if (from != null && to != null) {
			double timeInterval = to.getTarihSaat() - from.getTarihSaat();
			double timeAsMinute = (double)(timeInterval/(1000 * 60));
			speed = (float) ((float)(60 * distance(from, to)) / timeAsMinute);			
		} 
		return speed;		
	}
	
	public static double distance(double lat1, double lon1, double lat2, double lon2,
			char unit) {
		double theta = lon1 - lon2;
		double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
				+ Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
				* Math.cos(deg2rad(theta));
		dist = Math.acos(dist);
		dist = rad2deg(dist);
		dist = dist * 60 * 1.1515;
		if (unit == 'K') {
			dist = dist * 1.609344;
		} else if (unit == 'N') {
			dist = dist * 0.8684;
		}
		return (dist);
	}

	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	/* :: This function converts decimal degrees to radians : */
	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	private static double deg2rad(double deg) {
		return (deg * Math.PI / 180.0);
	}

	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	/* :: This function converts radians to decimal degrees : */
	/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
	private static double rad2deg(double rad) {
		return (rad * 180.0 / Math.PI);
	}
	
	
	public static String TEST_DEVICE_ID = "355067046828422"; 
										   
	/**
	 * IMEI number<br>
	 * 
	 * @return emulatorse 355067046828422 (sinan android)
	 */
	public static String getDeviceId () {
		if (isEmulator()) {
			return TEST_DEVICE_ID;
		}
		if ("unknown".equals(Constants.DEVICE_ID)) {
			TelephonyManager telephonyManager = (TelephonyManager)NGApplication.getAppContext().getSystemService(Context.TELEPHONY_SERVICE);
			String deviceID = telephonyManager.getDeviceId();		
			Constants.DEVICE_ID = deviceID;			
		}
		return Constants.DEVICE_ID;
	}	
	
	public static boolean isEmulator () {
		return Build.PRODUCT.toLowerCase().indexOf("google_sdk") >= 0;
	}
	
	public static boolean isNotEmpty (String str){
		return str != null && !("".equals(str));
	}
	
	public static boolean isEmpty (String str){
		return !isNotEmpty(str);
	}
	
	@SuppressWarnings("rawtypes")
	public static boolean isNotEmpty (Collection col){
		return col != null && col.size() > 0;
	}
	
	public static boolean isEmpty (@SuppressWarnings("rawtypes") Collection col){
		return !isNotEmpty(col);
	}

	
	public static void killApp(boolean killSafely) {
        if (killSafely) {
            /*
             * Notify the system to finalize and collect all objects of the app
             * on exit so that the virtual machine running the app can be killed
             * by the system without causing issues. NOTE: If this is set to
             * true then the virtual machine will not be killed until all of its
             * threads have closed.
             */
            System.runFinalizersOnExit(true);

            /*
             * Force the system to close the app down completely instead of
             * retaining it in the background. The virtual machine that runs the
             * app will be killed. The app will be completely created as a new
             * app in a new virtual machine running in a new process if the user
             * starts the app again.
             */
            System.exit(0);
        } else {
            /*
             * Alternatively the process that runs the virtual machine could be
             * abruptly killed. This is the quickest way to remove the app from
             * the device but it could cause problems since resources will not
             * be finalized first. For example, all threads running under the
             * process will be abruptly killed when the process is abruptly
             * killed. If one of those threads was making multiple related
             * changes to the database, then it may have committed some of those
             * changes but not all of those changes when it was abruptly killed.
             */
            android.os.Process.killProcess(android.os.Process.myPid());
        }

    }	
	
	// Checks whether the GPS hardware is present in the device
	public static boolean haveGPS(Context ctx)
	{
	    PackageManager pmgr = ctx.getPackageManager();
	    boolean gotGPS = pmgr.hasSystemFeature("android.hardware.location.gps");
	    return gotGPS;
	}

	public static boolean isGPSEnabled(Context ctx) {
		String GpsProvider = Settings.Secure.getString(ctx.getContentResolver(),
				Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

		if (GpsProvider.toLowerCase().indexOf("gps") >= 0 ) {
			return true;
		} else {
			return false;
		}
	}
	
	public static int getImageResource (NGLocation loc) {
		Status status = loc.getStatus();
		if (Status.UYGULAMA_ACILDI.equals(status))
			return R.drawable.ic_uygulamaacildi;
		else if (Status.DURDU.equals(status))
			return R.drawable.ic_durdu;
		else if (Status.HAREKET_EDIYOR.equals(status)) {
			return R.drawable.ic_hareketediyor;
		} else if (Status.UYGULAMA_KAPANDI.equals(status)) {
			return R.drawable.ic_uygulamakapandi;
		}
		return 0; //TODO 
	}
	
	/**
	 * TODO string.xml'den al 
	 * @param status
	 * @return
	 */
	public static String getFriendlyStatus (Status status) {
		if (Status.UYGULAMA_ACILDI.equals(status))
			return "Uygulama açıldı";
		else if (Status.DURDU.equals(status))
			return "Durdu";
		else if (Status.HAREKET_EDIYOR.equals(status)) {
			return "Hareket ediyor";
		}
		return status.name(); //TODO 
	}
	
	public static int toInt(String value){
		if (value == null || "".equals(value)) {
			return 0;
		}
		try {
			value = value.trim();
			return Integer.parseInt(value);
		} catch (Exception e) {
		}
		return 0;
	}
	
	public static String getFriendlyCommand(Command command) {
		Context ctx = NGApplication.getAppContext();
		CharSequence result = command.name();;
		if (Command.LOCATION_SIZE.equals(command)) {
			result = ctx.getText(R.string.txtLOCATION_SIZE);
		} else if (Command.MIN_DISTANCE.equals(command)) {
			result = ctx.getText(R.string.txtMIN_DISTANCE);			
		} else if (Command.MIN_TIME.equals(command)) {
			result = ctx.getText(R.string.txtMIN_TIME);			
		} else if (Command.SEND_FREQUENCY.equals(command)) {
			result = ctx.getText(R.string.txtMIN_SEND_FREQUENCY);						
		}
		return result.toString();
	}
	
	public static String getFriendlyTimeShort(Date dateTime) {
	    Date current = Calendar.getInstance().getTime();
	    long diffInSeconds = (current.getTime() - dateTime.getTime()) / 1000;

	    //diffInSeconds += (60 * 60 * 24);, test için
	    
	    long sec = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
	    long min = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
	    long hrs = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
	    long days = (diffInSeconds = (diffInSeconds / 24)) >= 30 ? diffInSeconds % 30 : diffInSeconds;
	    long months = (diffInSeconds = (diffInSeconds / 30)) >= 12 ? diffInSeconds % 12 : diffInSeconds;
	    long years = (diffInSeconds = (diffInSeconds / 12));
	    
	    String ago = " önce";
	    
	    if (years > 0) {
	        if (years == 1) {
	            return "Bir yıldan" + ago;
	        } else {
	            return "Yıllar" + ago;
	        }
	    } else if (months > 0) {
	        if (months == 1) {
	        	return "Bir ay" + ago;
	        } else {
	        	return months + " ay" + ago;
	        }
	    } else if (days > 0) {
	        if (days == 1) {
	            return "Dün";
	        } else {
	        	return days + " gün " + ago;
	        }
	    } else if (hrs > 0) {
	        if (hrs == 1) {
	        	return "Bir saat" + ago;
	        } else {
	            return hrs + " saat" + ago;
	        }
	    } else if (min > 0) {
	        if (min == 1) {
	            return "Bir dakika" + ago;
	        } else {
	            return (min + " dakika" + ago);
	        }
	    } else {
	        if (sec <= 1) {
	            return ("Bir saniye" + ago);
	        } else {
	            return (sec + " saniye" + ago);
	        }
	    }
	}
	
	public static int[] resolution (Activity activity){
		DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return new int[]{dm.widthPixels, dm.heightPixels};
	}
	
	public static String versionName () {
		PackageInfo pinfo;
		//int versionNumber = 0;
		String versionName = "nover";	
		try {
			pinfo = NGApplication.getAppContext().getPackageManager().getPackageInfo(NGApplication.getAppContext().getPackageName(), 0);
			//versionNumber = pinfo.versionCode;
			versionName = pinfo.versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return versionName;
	
	}
	
}
